<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2020/09/07
 * Time: 20:46
 * @link http://www.lmterp.cn
 */

namespace app\admin\controller\wms;

use app\admin\controller\BaseController;
use app\common\library\Tools;
use app\common\model\Account;
use app\common\model\Producer;
use app\common\model\Product;
use app\common\model\ProductBrand;
use app\common\model\ProductPlatformSku;
use app\common\model\ProductPurchase;
use app\common\model\ProductSpec;
use app\common\model\ProductStore;
use app\common\model\ProductUnit;
use app\common\model\Warehouse;
use app\common\service\product\ProductService;
use think\Paginator;

class ProductController extends BaseController
{
    /**
     * 商品列表
     * @return string|array
     * @date 2020/09/09
     * @author longli
     */
    public function index()
    {
        $this->assign('select_product', [
            'sku' => 'SKU',
            'spu' => 'SPU',
            'platform_sku' => '平台SKU',
            'name_ch' => '商品中文名',
            'name_en' => '商品英文名',
            'producer_name' => '供应商',
            'unit_id' => '计量单位',
        ]);
        $this->assign('account', Account::getAll());
        $this->assign("product_status", Product::$STATUS);
        $this->assign('create_date', [0 => '今天', -1 => '昨天', -6 => '7天前', -59 => '60天前']);
        $this->assign('sort', ['product_id' => '录入时间', 'name_ch' => '名称', 'brand' => '品牌', 'status' => '状态', 'model' => '型号']);
        $this->assign('status', Product::$STATUS);
        if($this->request->isAjax())
        {
            $products = $this->search();
            return apiResponsePage($products);
        }
        return $this->fetch("index");
    }

    /**
     * 搜索商品
     * @return Paginator
     * @date 2020/09/02
     * @author longli
     */
    private function search()
    {
        $search = $this->request->request();
        // 处理搜索条件
        $sField = ['sku', 'attr', 'color']; $purField = ['producer_id', 'producer_name']; $pField = Product::getTableFields();
        $pWhere = $sWhere = $purWhere = [];
        if(!empty($search['start_date'])) $pWhere[] = array_merge($pWhere, $this->parseLayuiRangeDate('create_time', $search['start_date']));

        if(isset($search['create_date'])) $pWhere = array_merge($pWhere, $this->parseScopeDateToWhere('create_time', $search['create_date']));

        foreach($search as $k => $v)
        {
            if(in_array($k, $pField))
            {
                $pWhere[] = [$k, 'in', $v];
            }
            else if(in_array($k, $sField))
            {
                $sWhere[$k] = $v;
            }
            else if(in_array($k, $purField))
            {
                $purWhere[$k] = $v;
            }
        }
        // 处理排序
        $sort = 'product_id desc';
        if(!empty($search['sort']) && $search['sort'] != 'product_id') $sort = "{$search['sort']} desc";

        // 模型关联
        $productModel = Product::where($pWhere)->order($sort)->with([
            'stores',
            'purchase' => function($query){$query->field(["product_id", "producer_name", "url", "is_default"]);},
            "admin"   => function($query){$query->field(["id","nickname"]);},
            'sbrand' => function($query){$query->field("brand_id,name_ch");},
            'category' => function($query){$query->field("cate_id,name");},
            'unit' => function($query){$query->field("unit_id,name_ch");},
            'images' => function($query){$query->field("product_id,image_url");},
        ]);
        // 处理平台 sku
        if(!empty($search['platform_sku']))
        {
            $productModel->where("product_id", "in", function($query)use($search)
            {
                $query->table(ProductPlatformSku::getTable())->where("platform_sku", "like", "%{$search['platform_sku']}%")->field("product_id");
            });
        }
        // 处理变体查询
        if(!empty($sWhere))
        {
            $productModel->where("product_id", "in", function($query) use($sWhere)
            {
                $query->table(ProductStore::getTable())->field("product_id");
                foreach($sWhere as $k => $v)
                {
                    $k == 'sku' && !Tools::contains($v, ',')
                        ? $query->where("sku", "like", "%{$v}%")
                        : $query->where($k, 'in', $v);
                }
            });
        }
        // 处理商品采购查询
        if(!empty($purWhere))
        {
            $productModel->where("product_id", "in", function($query) use($purWhere)
            {
                $query->table(ProductPurchase::getTable())->field("product_id");
                foreach($purWhere as $k => $v)
                {
                    $query->where($k, $v);
                }
            });
        }
        // 处理分页
        $limit = !empty($search['limit']) ? $search['limit'] : null;
        return $productModel->paginate($limit);
    }

    /**
     * 录入商品
     * @return string
     * @date 2020/09/09
     * @author longli
     */
    public function add()
    {
        $this->assign('brand', ProductBrand::getAll());
        $this->assign('unit', ProductUnit::getAll());
        $this->assign('status', Product::$STATUS);
        $this->assign('warehouse', Warehouse::getAll());
        $this->assign('producer', Producer::getAll());
        $this->assign('producer_defaults', Product::$IS_STATUS);
        $this->assign('producer_type', Producer::$LINE_TYPE);
        $this->assign('spec', ProductSpec::getAll()->toArray());
        $productId = $this->request->get("product_id");
        if(!empty($productId) && $product = Product::with(['stores', 'images', 'attrs', 'purchase'])->find($productId))
        {
            $this->assign("product", $product);
        }
        return $this->fetch('add');
    }

    /**
     * 查看商品详情
     * @return mixed
     * @date 2020/09/14
     * @author longli
     */
    public function look()
    {
        $productId = $this->request->get("product_id");
        $product = Product::with(['stores', 'images', 'sbrand', 'purchase', 'category'])->findOrFail($productId);
        $this->assign("product", $product);
        return $this->fetch('look');
    }

    /**
     * 更新商品状态
     * @date 2020/09/14
     * @author longli
     */
    public function update()
    {
        $productId = $this->request->post("product_id");
        if(empty($productId)) $this->error('非法请求');
        $field = $this->request->post("field");
        $value = $this->request->post("value");
        if((is_array($field) && !is_array($value)) || (empty($field) || (empty($value) && !is_numeric($value)))) $this->error('非法参数');
        if(is_array($field))
        {
            $data = [];
            foreach($field as $k => $f)
            {
                $data[$f] = $value[$k];
            }
        }
        else
        {
            $data = [$field => $value];
        }
        Product::editByProductId($productId, $data)
            ? $this->success('更新成功')
            : $this->error('更新失败');
    }

    /**
     * 保存商品
     * @date 2020/09/09
     * @author longli
     */
    public function save()
    {
        $json = $this->request->getContent();
        if(!Tools::isJson($json, $data)) $this->error("非法请求");
        $data = ProductService::getInstance()->parseRequestData($data);
        ProductService::getInstance()->addProduct($data)
             ? $this->success("保存成功")
             : $this->error("保存失败");
    }

    /**
     * 导出文件
     * @date 2020/09/13
     * @author longli
     */
    public function export()
    {
        $ids = $this->request->request("ids");
        $startDate = $this->request->request("start_date");
        $endDate = $this->request->request("end_date");
        if(empty($ids) && empty($startDate)) $this->error("非法导出，请检查导出条件");
        $condition = [];
        if(!empty($ids)) $condition[] = ['product.product_id', 'in', $ids];
        if(!empty($startDate)) $condition = array_merge($condition, $this->parseLayuiRangeDate('product.create_time', $startDate));
        $productExport = new \app\common\service\export\Product();
        $file = $productExport->runExcel($condition);
        $this->success("导出成功", '', ["src" => urlencode($file)]);
    }

    /**
     * 导入商品
     * @date 2020/09/13
     * @author longli
     */
    public function import()
    {
        $file = $this->request->request("path");
        if(empty($file)) $this->error("非法请求");
        $file = ProductService::getRootPath($file);
        $productImport = new \app\common\service\import\Product($file);
        try
        {
            $productImport->run();
            return apiResponse(\app\common\status\BaseStatus::CODE_NORMAL, [], '导入成功');
        }catch(\RuntimeException $e)
        {
            $this->error($e->getMessage());
        }
    }

    /**
     * 删除商品
     * @date 2020/09/02
     * @author longli
     */
    public function delete()
    {
        $ids = $this->request->get("ids");
        ProductService::getInstance()->deleteProductById($ids)
            ? $this->success('删除成功')
            : $this->error('删除失败');
    }

    /**
     * 获取自动生成 sku
     * @date 2020/09/09
     * @author longli
     */
    public function getskus()
    {
        $num = $this->request->get("num");
        $sku = $this->request->get("sku", '', 'trim');
        $spu = $this->request->get("spu", '', 'trim');
        if(Product::hasSPU($spu)) $this->error("SPU【{$spu}】已存在，请重新输入");
        if(empty($num) || $num < 1) $this->error('非法参数');
        $skus = empty($sku)
            ? ProductService::getInstance()->generateSameSku($num, $spu)
            : ProductService::getInstance()->addSameSku($sku, $num);
        $this->success('生成成功', '', !is_array($skus) ? [$skus]: $skus);
    }

    /**
     * 通过 sku 获取商品
     * @date 2020/11/05
     * @author longli
     */
    public function get()
    {
        $param = [];
        $sku = $this->request->get("sku", "", "trim");
        $storeId = $this->request->get("store_id", "", "trim");
        $more = $this->request->get("more", 0);
        $warehouseId = $this->request->get('warehouse_id');
        if(!empty($sku)) $param[] = ["sku", "like", "%{$sku}%"];
        if(!empty($storeId)) $param[] = ['store_id', '=', $storeId];
        if(empty($param)) $this->error('非法参数');
        $store = ProductStore::with(["product"=>function($query)
        {$query->with(["purchase"]);}])->where($param);
        if(!empty($warehouseId))
        {
            $store->whereIn('store_id', function($query)use($warehouseId)
            {
                $query->table(\app\common\model\WarehouseStock::getTable())
                    ->whereIn('warehouse_id', $warehouseId)
                    ->field(['store_id']);
            });
        }
        $store = !empty($more) ? $store->select() : $store->find();
        !empty($store) && !$store->isEmpty()
            ? $this->success('获取成功', '', $store->toArray())
            : $this->error('获取失败');
    }
}